package com.netty;

import com.netty.dto.Message;
import com.netty.dto.Person;
import com.netty.dto.Product;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

/**
 * @author CHL
 * @ClassName: SenderClient
 * @Description: 消息发送客户端
 * @date 2022/12/30 16:27
 * @Version 1.0
 */
public class SenderClient {
    public static String consumerHost;
    public static Integer consumerPort;

    private static void fetchInfos() {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline channelPipeline = socketChannel.pipeline();
                            channelPipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(SenderClient.class.getClassLoader())));
                            channelPipeline.addLast(new ObjectEncoder());
                            channelPipeline.addLast(new FetchRegistryInfosHandler());
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect("localhost", 8000).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }

    public static void sendMessage(Message message) {
        if (consumerHost == null || consumerPort == null) {
            fetchInfos();
        }

        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline channelPipeline = socketChannel.pipeline();
                            channelPipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(SenderClient.class.getClassLoader())));
                            channelPipeline.addLast(new ObjectEncoder());
                            channelPipeline.addLast(new SenderMessageHandler(message));
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect(consumerHost, consumerPort).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        Message message = new Message();
        message.setTopic("person");

        Person person = new Person();
        person.setName("瓜田李下");
        person.setAge(20);
        message.setContent(person);
        sendMessage(message);


        Message message2 = new Message();
        message.setTopic("product");

        Product product = new Product();
        product.setName("苹果");
        product.setPrice(10f);
        product.setNum(10);

        message2.setContent(product);
        sendMessage(message2);
    }

}
